// FIT_6204_Gorodilov_InSegView.cpp : implementation of the CFIT_6204_Gorodilov_InSegView class
//

#include "stdafx.h"
#include "FIT_6204_Gorodilov_InSeg.h"

#include "FIT_6204_Gorodilov_InSegDoc.h"
#include "FIT_6204_Gorodilov_InSegView.h"
#include "FIT_6204_Gorodilov_InSegDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CFIT_6204_Gorodilov_InSegView

IMPLEMENT_DYNCREATE(CFIT_6204_Gorodilov_InSegView, CScrollView)

BEGIN_MESSAGE_MAP(CFIT_6204_Gorodilov_InSegView, CScrollView)
	ON_WM_ERASEBKGND()
	ON_WM_SIZE()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(ID_EDIT_SWEEP, &CFIT_6204_Gorodilov_InSegView::OnEditSweep)
	ON_COMMAND(ID_EDIT_PROPERTIES, &CFIT_6204_Gorodilov_InSegView::OnEditProperties)
END_MESSAGE_MAP()

// CFIT_6204_Gorodilov_InSegView construction/destruction

CFIT_6204_Gorodilov_InSegView::CFIT_6204_Gorodilov_InSegView()
: m_pDC(NULL)
, m_pBitmap(NULL)
, m_pOldBitmap(NULL)
, m_iPointFocused((UINT)-1)
, m_iPointPeeked((UINT)-1)
{
	m_pPointPen = new CPen(0, 0, RGB(0,128,255));
	m_pPointBrush = new CBrush(RGB(0,128,255));
	m_pPointBrushPeeked = new CBrush(RGB(255,0,0));
	m_pPointBrushFocused = new CBrush(RGB(0,255,10));
	m_pLinePen = new CPen(0, 0, RGB(255, 0, 55));
	m_pLinePen2 = new CPen(0, 1, RGB(0, 0, 0));
}

CFIT_6204_Gorodilov_InSegView::~CFIT_6204_Gorodilov_InSegView()
{
	if (m_pDC) {
		if (m_pOldBitmap) {
			m_pDC->SelectObject(m_pOldBitmap);
			m_pOldBitmap = NULL;
		}
		delete m_pDC;
	}
	if (m_pBitmap) {
		delete m_pBitmap;
	}
	if (m_pPointBrush) {
		delete m_pPointBrush;
	}
	if (m_pPointPen) {
		delete m_pPointPen;
	}
	if (m_pLinePen) {
		delete m_pLinePen;
	}
	if (m_pLinePen2) {
		delete m_pLinePen2;
	}
	if (m_pPointBrushPeeked) {
		delete m_pPointBrushPeeked;
	}
	if (m_pPointBrushFocused) {
		delete m_pPointBrushFocused;
	}
}

BOOL CFIT_6204_Gorodilov_InSegView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CScrollView::PreCreateWindow(cs);
}

// CFIT_6204_Gorodilov_InSegView drawing

void CFIT_6204_Gorodilov_InSegView::OnDraw(CDC* pDC)
{
	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CSize lScrollSize = pDoc->GetScrollSize();
	CRect clientRect;
	GetClientRect(&clientRect);
	int width = lScrollSize.cx;
	int height = lScrollSize.cy;
	if (clientRect.right - clientRect.left > width) {
		width = clientRect.right - clientRect.left;
	}
	if (clientRect.bottom - clientRect.top > height) {
		height = clientRect.bottom - clientRect.top;
	}

	m_pDC->FillSolidRect(0, 0, 
		width, height,
		RGB(50,50,50));

	m_pDC->FillSolidRect(0, 0, 
		lScrollSize.cx, lScrollSize.cy,
		RGB(250,250,210));

	CPoint radiusPoint(4,4);

	CPen *pOldPen = m_pDC->SelectObject(m_pPointPen);
	CBrush *pOldBrush = m_pDC->SelectObject(m_pPointBrush);
	INT_PTR count = pDoc->GetLinesCount();
	for (INT_PTR index = 0; index < count; index++) {
		CFIT_6204_Gorodilov_Line line = pDoc->GetLine(index);
		CFIT_6204_Gorodilov_Point left = line.GetLeftPoint();
		CFIT_6204_Gorodilov_Point right = line.GetRightPoint();
		
		CPen *pOldLinePen = m_pDC->SelectObject(m_pLinePen);
		CPoint leftI((int)(left.x + 0.5), (int)(left.y + 0.5));
		CPoint rightI((int)(right.x + 0.5), (int)(right.y + 0.5));
		m_pDC->MoveTo(leftI);
		m_pDC->LineTo(rightI);
		m_pDC->SelectObject(pOldLinePen);

		CBrush *pOldPeekedBrush = NULL;
		if (index == count - 1 && pDoc->m_bIsSecondPoint) {
			pOldPeekedBrush = m_pDC->SelectObject(m_pPointBrushPeeked);
		}
		CRect rect((CPoint)(leftI - radiusPoint),
			CSize(radiusPoint.x*2, radiusPoint.y*2));
		m_pDC->Ellipse(rect);
		rect.MoveToXY((CPoint)(rightI - radiusPoint));
		m_pDC->Ellipse(rect);
		if (index == count - 1) {
			m_pDC->SelectObject(pOldPeekedBrush);
		}
	}

	pOldBrush = m_pDC->SelectObject(m_pPointBrushFocused);
	count = pDoc->I.GetCount();
	for (INT_PTR index = 0; index < count; index++) {
		CFIT_6204_Gorodilov_Point left = pDoc->I.GetAt(index);
		CPoint leftI((int)(left.x + 0.5), (int)(left.y + 0.5));
		CRect rect((CPoint)(leftI - radiusPoint),
			CSize(radiusPoint.x*2, radiusPoint.y*2));
		m_pDC->Ellipse(rect);
	}
	m_pDC->SelectObject(pOldBrush);

	m_pDC->SelectObject(pOldPen);
	m_pDC->SelectObject(pOldBrush);
	
	pDC->BitBlt(0, 0,
		width, height,
		m_pDC,0,0,SRCCOPY);
}

void CFIT_6204_Gorodilov_InSegView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CSize lScrollSize = pDoc->GetScrollSize();

	SetScrollSizes(MM_TEXT, lScrollSize);
	if (m_pDC) {
		if (m_pOldBitmap) {
			m_pDC->SelectObject(m_pOldBitmap);
			m_pOldBitmap = NULL;
		}
		delete m_pDC;
	}
	if (m_pBitmap) {
		delete m_pBitmap;
	}

	m_pDC = new CDC();
	m_pDC->CreateCompatibleDC(GetDC());

	int width = lScrollSize.cx;
	int height = lScrollSize.cy;
	CRect clientRect;
	GetClientRect(&clientRect);
	if (clientRect.right - clientRect.left > width) {
		width = clientRect.right - clientRect.left;
	}
	if (clientRect.bottom - clientRect.top > height) {
		height = clientRect.bottom - clientRect.top;
	}
	m_pBitmap = new CBitmap();
	if (m_pBitmap->CreateCompatibleBitmap(GetDC(),
		width, height)) {
		m_pOldBitmap = m_pDC->SelectObject(m_pBitmap);
	}
}


// CFIT_6204_Gorodilov_InSegView diagnostics

#ifdef _DEBUG
void CFIT_6204_Gorodilov_InSegView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CFIT_6204_Gorodilov_InSegView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CFIT_6204_Gorodilov_InSegDoc* CFIT_6204_Gorodilov_InSegView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFIT_6204_Gorodilov_InSegDoc)));
	return (CFIT_6204_Gorodilov_InSegDoc*)m_pDocument;
}
#endif //_DEBUG


// CFIT_6204_Gorodilov_InSegView message handlers

BOOL CFIT_6204_Gorodilov_InSegView::OnEraseBkgnd(CDC* /*pDC*/)
{
	return TRUE;
}

void CFIT_6204_Gorodilov_InSegView::OnSize(UINT nType, int cx, int cy)
{
	CScrollView::OnSize(nType, cx, cy);

	OnInitialUpdate();
}

void CFIT_6204_Gorodilov_InSegView::OnLButtonDown(UINT nFlags, CPoint point)
{
	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CPoint curPoint = point + GetScrollPosition();
	
	if (pDoc->m_bIsSecondPoint) {
		INT_PTR lastIndex = pDoc->GetLinesCount() - 1;
		CFIT_6204_Gorodilov_Line line = pDoc->GetLine(lastIndex);
		line.UpdatePoints(m_pCurPoint, curPoint);
		pDoc->UpDateLine(lastIndex,line);
		line.UpdatePoints(m_pCurPoint, m_pCurPoint);
		pDoc->AddLine(line);
		m_pCurPoint = curPoint;
	} else {
		m_pCurPoint = curPoint;
		pDoc->m_bIsSecondPoint = TRUE;

		CFIT_6204_Gorodilov_Line line(m_pCurPoint, m_pCurPoint);
		pDoc->AddLine(line);
	}
	pDoc->UpdateAllViews(NULL);
	
	CScrollView::OnLButtonDown(nFlags, point);
}

void CFIT_6204_Gorodilov_InSegView::OnMouseMove(UINT nFlags, CPoint point)
{
	CScrollView::OnMouseMove(nFlags, point);
	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CPoint pMousePoint = point + GetScrollPosition();
	
	if (pDoc->m_bIsSecondPoint) {
		INT_PTR lastIndex = pDoc->GetLinesCount() - 1;
		CFIT_6204_Gorodilov_Line line = pDoc->GetLine(lastIndex);
		line.UpdatePoints(pMousePoint, m_pCurPoint);
		pDoc->UpDateLine(lastIndex,line);
	}

	pDoc->UpdateAllViews(NULL);
}

void CFIT_6204_Gorodilov_InSegView::OnRButtonDown(UINT nFlags, CPoint point)
{
	CScrollView::OnMouseMove(nFlags, point);
	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	pDoc->m_bIsSecondPoint = FALSE;

	pDoc->UpdateAllViews(NULL);

	CScrollView::OnRButtonDown(nFlags, point);
}

void CFIT_6204_Gorodilov_InSegView::OnEditSweep()
{
	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	pDoc->Sweep();
	pDoc->UpdateAllViews(NULL);
}

void CFIT_6204_Gorodilov_InSegView::OnEditProperties()
{
	CFIT_6204_Gorodilov_InSegDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CSize scrollSize = pDoc->GetScrollSize();
	CFIT_6204_Gorodilov_InSegDlg dlg(this, scrollSize.cx, scrollSize.cy);
	if (IDOK == dlg.DoModal()) {
		scrollSize.cx = dlg.GetWidth();
		scrollSize.cy = dlg.GetHeight();
		pDoc->m_sScrollSize = scrollSize;
		pDoc->OnNewDocument();
		OnInitialUpdate();
	}
}
